using System.Xml.Serialization;
using GTA;
using GTA.Native;
using GTA.UI;

namespace CustomPeds;

public class Origin
{
    public VehicleDrivingFlags drivingFlags = VehicleDrivingFlags.DrivingModeAvoidVehicles;
    public bool AutoAttack = true;
    public bool Follow = true;
    public bool Invincible;
    public bool CanWearHelmet = true;
    public bool AvoidHazards = true;
    public int HazardSensitivityIndex = 1; // 0:低 1:中 2:高
    public bool AutoExitOnReach = false;
    public int SeatIndex = -1;
    public bool IsTaskDriveToWaypoint;

    [XmlIgnore]
    public Main.Member Member;

    [XmlIgnore]
    public Ped Character;

    public Skin skin = new Skin();

    private static FeedPost notify1;
    private static FeedPost notify2;

    private bool isExitingVehicle;

    public void BuildPedData(Ped ped, Main.Member member, bool isAddonPed)
    {
        Member = member;
        Character = ped;
        skin = new Skin(ped, isAddonPed);
    }

    public void DetectDriverAndWaypoint()
    {
        // 只要 P1 或 P2 处于载具中即可，不要求当前已是驾驶位
        bool p1InVeh = Main.P1.Character != null && Main.P1.Character.IsInVehicle();
        bool p2InVeh = Main.P2.Character != null && Main.P2.Character.IsInVehicle();
        if (!p1InVeh && !p2InVeh) return;
        try
        {
            if (!Game.IsWaypointActive)
            {
                Function.Call((Hash)0xE8A25867FBA3B05Eul, 0, 199, 1f);
                Script.Wait(3000);
            }
            if (Game.IsWaypointActive)
            {
                if (Member == Main.Member.P1)
                {
                    Main.P1.TaskDriveToWaypoint();
                }
                else
                {
                    Main.P2.TaskDriveToWaypoint();
                }
            }
            else
            {
                Notification.PostTicker(TextSetting.dtw_Notify_NeedWaypoint, true, false);
            }
        }
        catch (System.Exception ex)
        {
            Notification.PostTicker($"检测路点失败: {ex.Message}", true, false);
        }
    }

    private void TaskDriveToWaypoint()
    {
        if (Main.P1.Character == null || Main.P2.Character == null)
        {
            Notification.PostTicker("未检测到可用Ped，取消执行", true, false);
            return;
        }
        if (IsTaskDriveToWaypoint)
        {
            return;
        }
        IsTaskDriveToWaypoint = true;
        isExitingVehicle = false;
        try
        {
            var waypointPosition = World.WaypointPosition;
            var currentVehicle = (Main.P1.Character != null && Main.P1.Character.IsInVehicle()) ? Main.P1.Character.CurrentVehicle : ((Main.P2.Character != null && Main.P2.Character.IsInVehicle()) ? Main.P2.Character.CurrentVehicle : null);
            if (currentVehicle == null || !currentVehicle.Exists())
            {
                IsTaskDriveToWaypoint = false;
                return;
            }
            var speed = Function.Call<float>((Hash)0xF417C2502FFFED43ul, currentVehicle.Model.Hash);

            if (Member == Main.Member.P1)
            {
                Main.EnsureDriverAndPassenger(currentVehicle, Main.P1.Character, (Main.P2.Character != null && Main.P2.Character.IsAlive && Main.P2.Follow) ? Main.P2.Character : null);
                Main.P1.Character.Task.DriveTo(currentVehicle, waypointPosition, 8f, Main.P1.drivingFlags, speed);

                var startTime = System.DateTime.Now;
                while (World.CalculateTravelDistance(Main.P1.Character.Position, waypointPosition) >= 10f)
                {
                    if (System.DateTime.Now.Subtract(startTime).TotalSeconds > 1800)
                    {
                        Notification.PostTicker("驾驶超时，任务结束", true, false);
                        TaskDriveToWaypointEnd(currentVehicle, reach: false);
                        return;
                    }
                    OtherHelper.DisplayHelpTextThisFrame($"~INPUT_CONTEXT~ {TextSetting.dtw_HelpText_End}~n~" + $"~INPUT_VEH_ACCELERATE~ {TextSetting.dtw_HelpText_SpeedUp}", loop: true);
                    Script.Wait(200);
                    if (Game.IsControlPressed(Control.Context))
                    {
                        TaskDriveToWaypointEnd(currentVehicle, reach: false);
                        return;
                    }
                    if (Game.IsControlPressed(Control.VehicleAccelerate))
                    {
                        currentVehicle.ApplyForce(currentVehicle.ForwardVector * 3f);
                    }

                    if (Main.IsPedDriverOfCurrentVehicle(Main.P1.Character)) continue;
                    TaskDriveToWaypointEnd(currentVehicle, reach: false);
                    return;
                }
            }
            // P2 驾驶逻辑（移除多余上下车动画，直接就位并驾驶）
            if (Member == Main.Member.P2)
            {
                // 直接就位：P2 驾驶，P1 副驾（WarpIn，避免动画）
                Main.EnsureDriverAndPassenger(currentVehicle, Main.P2.Character, (Main.P1.Character != null && Main.P1.Character.IsAlive) ? Main.P1.Character : null);

                // 开始驾驶（简化逻辑，移除多余提示/施力/重复指令）
                var dist0 = World.CalculateTravelDistance(Main.P2.Character.Position, waypointPosition);
                var targetSpeed = ComputeGirlfriendTargetSpeed(currentVehicle, dist0, speed);
                Main.P2.Character.VehicleDrivingFlags = Main.P2.drivingFlags;
                Main.P2.Character.Task.DriveTo(currentVehicle, waypointPosition, 8f, Main.P2.drivingFlags, targetSpeed);

                var startTimeP2 = System.DateTime.Now;
                while (World.CalculateTravelDistance(Main.P2.Character.Position, waypointPosition) >= 10f)
                {
                    if (System.DateTime.Now.Subtract(startTimeP2).TotalSeconds > 1800)
                    {
                        Notification.PostTicker("驾驶超时，任务结束", true, false);
                        TaskDriveToWaypointEnd(currentVehicle, reach: false);
                        return;
                    }
                    Script.Wait(250);
                    if (!Main.IsPedDriverOfCurrentVehicle(Main.P2.Character))
                    {
                        TaskDriveToWaypointEnd(currentVehicle, reach: false);
                        return;
                    }
                }
            }
            TaskDriveToWaypointEnd(currentVehicle, reach: true);
        }
        catch (System.Exception ex)
        {
            Notification.PostTicker($"驾驶任务失败: {ex.Message}", true, false);
            IsTaskDriveToWaypoint = false;
        }
    }

    private void TaskDriveToWaypointEnd(Vehicle vehicle, bool reach)
    {
        if (isExitingVehicle)
        {
            return;
        }
        isExitingVehicle = true;
        IsTaskDriveToWaypoint = false;
        try
        {
            Function.Call((Hash)0x8DFCED7A656F8802ul, true);
            vehicle.Speed = 0f;
            // 根据选项决定是否自动下车
            if (AutoExitOnReach)
            {
                if (Main.P1.Character != null && Main.P1.Character.IsAlive)
                {
                    Main.P1.Character.Task.LeaveVehicle();
                }
                if (Main.P2.Character != null && Main.P2.Character.IsAlive)
                {
                    Main.P2.Character.Task.LeaveVehicle();
                }
                Script.Wait(2000);
                if (Main.P1.Character != null && Main.P1.Character.IsAlive)
                {
                    Main.P1.Character.Task.ClearAllImmediately();
                }
                if (Main.P2.Character != null && Main.P2.Character.IsAlive)
                {
                    Main.P2.Character.Task.ClearAllImmediately();
                }
            }
            else
            {
                // 不下车，仅清理任务
                if (Main.P1.Character != null && Main.P1.Character.IsAlive)
                {
                    Main.P1.Character.Task.ClearAllImmediately();
                }
                if (Main.P2.Character != null && Main.P2.Character.IsAlive)
                {
                    Main.P2.Character.Task.ClearAllImmediately();
                }
            }
            if (reach)
            {
                Notification.PostTicker(TextSetting.dtw_Notify_Reach, true, false);
            }
        }
        catch (System.Exception ex)
        {
            Notification.PostTicker($"结束驾驶任务失败: {ex.Message}", true, false);
        }
        finally
        {
            isExitingVehicle = false;
        }
    }

    private VehicleSeat GetFirstAvailablePassengerSeat(Vehicle vehicle)
    {
        try
        {
            if (vehicle == null || !vehicle.Exists())
            {
                return VehicleSeat.Any;
            }
            // SHVDN3 无 PassengerSeats，按最多 16 个乘客位扫描（原生索引 0..15，-1 为 Driver）
            for (int i = 0; i < 16; i++)
            {
                var seat = (VehicleSeat)i;
                if (Main.IsSeatFree(vehicle, seat))
                {
                    return seat;
                }
            }
            return VehicleSeat.Any;
        }
        catch
        {
            return VehicleSeat.Any;
        }
    }

    public static string GetPedModelName(Model pedModel)
    {
        try
        {
            return ((PedHash)System.Convert.ToUInt32(pedModel.ToString(), 16)).ToString();
        }
        catch
        {
            return "Unknown";
        }
    }

    public static void ShowNotify(string text1, bool blinking1 = false, string text2 = "", bool blinking2 = false)
    {
        if (!string.IsNullOrEmpty(text1))
        {
            notify1 = Notification.PostTicker(text1, blinking1, false);
        }
        if (!string.IsNullOrEmpty(text2))
        {
            notify2 = Notification.PostTicker(text2, blinking2, false);
        }
    }

    public static void NotifyAllClear()
    {
        if (notify1 != null)
        {
            notify1.Delete();
            notify1 = null;
        }

        if (notify2 == null) return;
        notify2.Delete();
        notify2 = null;
    }

    public static uint GetHash(string str)
    {
        try
        {
            var num = 0u;
            var array = str.ToLower().ToCharArray();
            foreach (var t in array)
            {
                num += t;
                num += num << 10;
                num ^= num >> 6;
            }
            num += num << 3;
            num ^= num >> 11;
            return num + (num << 15);
        }
        catch
        {
            return 0;
        }
    }

    private float ComputeGirlfriendTargetSpeed(Vehicle vehicle, float distance, float baseSpeed)
    {
        try
        {
            // 基于车型基础能力（baseSpeed）做缩放，加入距离分段逻辑
            // 远距离：0.9x 基础；中距离（80-120）：0.7x；近距离（30-80）：0.5x；超近（<30）：0.3x
            float scale;
            if (distance >= 120f) scale = 0.9f;
            else if (distance >= 80f) scale = 0.7f;
            else if (distance >= 30f) scale = 0.5f;
            else scale = 0.3f;

            // 加一点最小速度兜底，避免过慢
            var minKmh = 18f; // ~5 m/s
            var speed = baseSpeed * scale;
            if (speed < minKmh) speed = minKmh;
            // 限制上限，避免过快
            var maxKmh = 110f;
            if (speed > maxKmh) speed = maxKmh;
            return speed;
        }
        catch
        {
            return baseSpeed;
        }
    }
}


